﻿#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <future>


void print_id(int id) {
	std::cout << "ID: " << id << ", Thread ID: " << std::this_thread::get_id() << std::endl;
}

int Sum = 0;
void sum(int a, int b) {
	Sum += a + b;
}
// 简单的函数，在线程中执行
void print_message(const std::string& message, int delay) {
	std::this_thread::sleep_for(std::chrono::milliseconds(delay));
	std::cout << message << std::endl;
}


std::mutex mtx; // 创建一个全局 mutex 对象
int shared_resource = 0; // 共享资源
// 线程函数
void increment() {
	std::lock_guard<std::mutex> lock(mtx); // 上锁，保证线程安全
	++shared_resource;
	std::cout << "Incremented shared_resource to " << shared_resource << std::endl;
	// lock 在 lock_guard 离开作用域时自动释放
}



std::mutex mtx2; // 创建一个全局 mutex 对象
//std::lock_guard 是一个 RAII 风格的锁管理器，用于自动管理锁的生命周期。
void print_thread_id(int id) {
	std::lock_guard<std::mutex> lock(mtx2);
	std::cout << "Thread ID: " << id << std::endl;
}

std::mutex mtx3; // 创建一个全局 mutex 对象
//std::unique_lock 提供了比 std::lock_guard 更灵活的锁管理。
void print_thread_id2(int id) {
	std::unique_lock<std::mutex> lock(mtx3);
	std::cout << "Thread ID: " << id << std::endl;
	lock.unlock(); // 可以手动解锁
}



std::mutex mtx4; // 创建一个全局 mutex 对象
//std::condition_variable 用于线程间的等待和通知。
std::condition_variable cv;
bool ready = false;

void print_id2(int id) {
	std::unique_lock<std::mutex> lock(mtx4);
	std::cout << "加锁，等待任务完成" << id << std::endl;
	cv.wait(lock, [] { return ready; });
	std::cout << "Thread ID: " << id << std::endl;
}

void set_ready() {
	std::unique_lock<std::mutex> lock(mtx4);
	ready = true;
	cv.notify_all();
	std::cout << "解锁，任务完成"  << std::endl;
}



//std::future 和 std::promise 用于线程间的结果传递。
void calculate_square(std::promise<int>&& p, int x) {
	p.set_value(x * x);
}



//std::async 用于启动异步任务，并返回一个 std::future。
int calculate_square2(int x) {
	return x * x;
}


int main()
{
	std::cout << "多线程的基本使用\n";
	std::thread t1(print_id, 1);
	std::thread t2(print_id, 2);

	//调用 join() 方法来等待线程完成,join() 方法会阻塞当前线程，直到被调用的线程完成执行。
	t1.join();
	t2.join();

	//销毁线程
	//当线程执行完毕后，你可以使用 detach() 方法来分离线程，或者让 std::thread 对象超出作用域自动销毁。
	//t1.detach(); // 线程将继续运行，但无法再被 join 或 detach


	//并行运算
	int a = 5;
	int b = 10;

	std::thread sumt1(sum, a, b);
	std::thread sumt2(sum, a, b);

	sumt1.join();
	sumt2.join();

	std::cout << "Sum: " << Sum << std::endl; // 输出结果：Sum: 30

	// 创建两个线程，执行 print_message 函数
	std::thread tt1(print_message, "Hello from thread 1", 1000);
	std::thread tt2(print_message, "Hello from thread 2", 500);

	// 等待线程 t1 完成 ，joinable(): 检查线程是否可被 join 或 detach。
	if (tt1.joinable()) {
		tt1.join();
	}

	// 等待线程 t2 完成
	if (tt2.joinable()) {
		tt2.join();
	}


	std::thread ttest(
		[]() {
			std::cout << "在线程中使用lambda表达式代替方法" << "\n";
		});
	ttest.join();





	std::thread incrementt1(increment);
	std::thread incrementt2(increment);

	incrementt1.join(); // 等待线程 t1 完成
	incrementt2.join(); // 等待线程 t2 完成

	std::cout << "Final value of shared_resource: " << shared_resource << std::endl;


	std::thread lock_guardt1(print_thread_id, 1);
	std::thread lock_guardt2(print_thread_id, 2);
	lock_guardt1.join();
	lock_guardt2.join();



	std::thread unique_lockt1(print_thread_id2, 1);
	std::thread unique_lockt2(print_thread_id2, 2);
	unique_lockt1.join();
	unique_lockt2.join();







	std::thread condition_variablet1(print_id2, 1);
	std::thread condition_variablet2(print_id2, 2);

	std::this_thread::sleep_for(std::chrono::seconds(1));
	set_ready();

	condition_variablet1.join();
	condition_variablet2.join();



	std::promise<int> p;
	std::future<int> f = p.get_future();
	std::thread t(calculate_square, std::move(p), 5);
	std::cout << "Square: " << f.get() << std::endl;
	t.join();




	std::future<int> result = std::async(calculate_square2, 5);
	std::cout << "Square: " << result.get() << std::endl;
	




	std::cout << "Main thread finished." << std::endl;
	return EXIT_SUCCESS;
}
